/******************************************************************************* * Signavio Core Components * Copyright (C) 2012 Signavio GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. ******************************************************************************/ package org.oryxeditor.server.diagram; import org.json.JSONException; import org.json.JSONObject; import org.oryxeditor.server.diagram.util.NumberUtil; /** * Represents a 2D Point on a canvas. Uses double precision coordinates * * @author Philipp Maschke */ public class Point{ Double x; Double y; /** * Creates a new Point with x and y coordinates * @param x * @param y */ public Point(Number x, Number y) { if (x == null) x = 0; if (y == null) y = 0; this.set(x.doubleValue(), y.doubleValue()); } /** * Creates a new Point with the coordinates of the given point * @param point */ public Point(Point point) { this.set(point); } /** * Creates a new point with a json like stucture of the x/y coordinates. * @param point * @throws JSONException */ public Point(String point) throws JSONException{ this.set(point); } /** * Creates a new point with a json of the x/y coordinates. * @param point * @throws JSONException */ public Point(JSONObject point) throws JSONException{ this.set(point); } /** * Move the point relative to the coordinates * @param x * @param y */ public void moveBy(double x, double y){ this.add(x, y); } /** * Move the point relative to the point * @param point */ public void moveBy(Point point){ this.add(point); } /** * Move the point absolute to the coordinates * @param x * @param y */ public void moveTo(double x, double y){ this.set(x, y); } /** * Move the point relative to the point * @param point */ public void moveTo(Point point){ this.set(point); } /** * Move the point absolute to the coordinates * @param x * @param y */ public void set(double x, double y){ this.setX(x); this.setY(y); } /** * Move the point absolut to the point * @param point */ public void set(Point point){ this.set(point.getX(), point.getY()); } /** * Set the point regarding the coordinates in the json like structure * @param point * @throws JSONException */ public void set(String point) throws JSONException{ this.set(new JSONObject(point)); } /** * Set the point regarding the coordinates in the json * @param point * @throws JSONException */ public void set(JSONObject point) throws JSONException{ this.set(point.getDouble("x"), point.getDouble("y")); } /** * @return the x */ public Double getX() { return x; } /** * @param x the x to set */ public void setX(Double x) { this.x = x; } /** * @return the y */ public Double getY() { return y; } /** * @param y the y to set */ public void setY(Double y) { this.y = y; } /** * Clones the point and returns a new one */ public Point copy(){ return new Point(this); } public void subtract(double x, double y){ this.x -= x; this.y -= y; } public void subtract(Point point){ this.subtract(point.getX(), point.getY()); } public void subtract(double a){ this.subtract(a, a); } public void add(double x, double y){ this.x += x; this.y += y; } public void add(Point point){ this.add(point.getX(), point.getY()); } public void add(double a){ this.add(a, a); } public void multiply(double x, double y){ this.x *= x; this.y *= y; } public void multiply(Point point){ this.multiply(point.getX(), point.getY()); } public void multiply(double a){ this.multiply(a, a); } public void divide(double x, double y){ if (x == 0 || y == 0){ throw new IllegalArgumentException("Attempted division with 0!"); } this.x /= x; this.y /= y; } public void divide(Point point){ this.divide(point.getX(), point.getY()); } public void divide(double a){ this.divide(a, a); } /** * Return a json representation of the point. * @return * @throws JSONException */ public JSONObject toJSON() throws JSONException{ JSONObject pos = new JSONObject(); pos.put("x", this.getX()); pos.put("y", this.getY()); return pos; } /** * Return a string representation of the point * in a json like structure. * In case of a JSONException, it returns super.toString(). * @return */ public String toString(){ try { return this.toJSON().toString(); } catch (JSONException e) { return super.toString(); } } /* (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((x == null) ? 0 : x.hashCode()); result = prime * result + ((y == null) ? 0 : y.hashCode()); return result; } /** * Checks for object equality first. * If other object is a point then returns true if their coordinates * are numerically equal (using {@link Double#compareTo(Double)} */ @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Point other = (Point) obj; if (x == null) { if (other.x != null) return false; } else if (x.compareTo(other.x) != 0) return false; if (y == null) { if (other.y != null) return false; } else if (y.compareTo(other.y) != 0) return false; return true; } /** * * @param other the other point * @return whether both coordinates of the two points are same * (allowing for a minimal difference; see {@link NumberUtil#areNumbersSame(Number, Number)}) */ public boolean hasSameCoordinatesAs(Point other){ return NumberUtil.areNumbersSame(getX(), other.getX()) && NumberUtil.areNumbersSame(getY(), other.getY()); } /** * * @param other the other point * @param maxDelta maximum allowed difference per coordinate * @return whether both coordinates of the two points are same (allowing for the given delta) */ public boolean hasSameCoordinatesAs(Point other, double maxDelta){ return NumberUtil.areNumbersWithinDelta(getX(), other.getX(), maxDelta) && NumberUtil.areNumbersWithinDelta(getY(), other.getY(), maxDelta); } /** * Calculates the sum of two Points * * @param p1 * @param p2 * @return the sum of p1 and p2 in a new Point object */ public static Point getSum(Point p1, Point p2) { Point result = new Point(p1); result.add(p2); return result; } /** * Calculates the difference of two Points * * @param p1 * @param p2 * @return the difference of p1 and p2 in a new Point object */ public static Point getDifference(Point p1, Point p2) { Point result = new Point(p1); result.subtract(p2); return result; } /** * Calculates the product of two Points * * @param p1 * @param p2 * @return the product of p1 and p2 in a new Point object */ public static Point getProduct(Point p1, Point p2) { Point result = new Point(p1); result.multiply(p2); return result; } /** * Calculates the quotient of two Points * * @param p1 * @param p2 * @return the quotient of p1 and p2 in a new Point object */ public static Point getQuotient(Point p1, Point p2) { Point result = new Point(p1); result.divide(p2); return result; } }